<template>
    <div class="table-wrapper">
        <div class="header-wrapper" ref="headerWrapper">
            <slot name="tableHeader"></slot>
        </div>
        <div class="body-wrapper" ref="bodyWrapper" @scroll="handleScroll">
            <div class="virtual-list-phantom" :style="{ height: totalHeight + 'px', width: tabWidth + 'px' }"></div>
            <div class="virtual-list" :style="{ transform: `translateY(${offset}px)` }">
                <slot name="tableBody" v-for="(rowData) in visibleData" :rowData="rowData" >
                </slot>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">

interface VirtualTableProps {
    data: Record<string, any>[];
    tabWidth: number;
}

const props = defineProps<VirtualTableProps>();

const headerWrapper = ref<HTMLElement | null>();
const bodyWrapper = ref<HTMLElement | null>();


//***************虚拟滚动************
const itemHeight = 40;
const bufferSize = 20;
// const itemWidth = computed(() => columns.value.length * 200);

const state = reactive({
    visibleStartIndex: 0,  // 可见数据起始索引
    visibleEndIndex: 20,   // 可见数据结束索引
});


// 总高度计算
const totalHeight = computed(() => {
    return 1 + props.data.length * itemHeight;
});

// 可见数据计算
const visibleData = computed(() => {
    return props.data.slice(state.visibleStartIndex, state.visibleEndIndex);
});

let lastScrollLeft = 0;
let lastScrollTop = 0;

function handleScroll(event: any) {
    const scrollTop = event.target.scrollTop;
    const scrollLeft = event.target.scrollLeft;

    if (lastScrollTop !== scrollTop && bodyWrapper.value) {
        // 计算当前滚动位置的索引
        const currentStartIndex = Math.floor(scrollTop / itemHeight);
        const visibleItemCount = Math.ceil(bodyWrapper.value.clientHeight / itemHeight);

        // 更新可见数据起始和结束索引
        state.visibleStartIndex = Math.max(0, currentStartIndex - bufferSize);
        state.visibleEndIndex = Math.min(props.data.length, currentStartIndex + visibleItemCount + bufferSize);
        //记录上一次的滚动条y轴位置 
        lastScrollTop = scrollTop;
    }



    //body和header横向滚动同步你
    if (headerWrapper.value && lastScrollLeft !== scrollLeft) {
        headerWrapper.value.scrollLeft = scrollLeft;
        //记录上一次的滚动条x轴位置
        lastScrollLeft = scrollLeft;
    }
}

// 偏移量计算
const offset = computed(() => {
    return state.visibleStartIndex * itemHeight;
});

// 初始化和更新滚动处理器
onMounted(() => {
    if (bodyWrapper.value) {
        const visibleItemCount = Math.ceil(bodyWrapper.value.clientHeight / itemHeight);
        state.visibleEndIndex = visibleItemCount + bufferSize;
    }
});

// 监听data变化更新滚动
// watch(data.value, () => {
//     handleScroll({ target: bodyWrapper.value });
// });
</script>

<style scoped lang="scss">
.table-wrapper {
    width: 100%;
    // max-width: 1910px;
    height: 100%;
    background-color: var(--el-bg-color-overlay);
    border-radius: var(--el-border-radius-base);
    white-space: nowrap;

    .header-wrapper {
        padding-bottom: 10px;
        border-bottom: 1px solid var(--el-border-color-lighter);
        overflow: hidden;
        /* 防止水平滚动条出现在header */
        font-size: 13px;
        font-weight: bold;
        color: var(--el-text-color-primary)
    }

    .body-wrapper {
        width: 100%;
        overflow: auto;
        height: calc(100% - 32px);
        position: relative;
        font-size: 12px;

        .virtual-list-phantom {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            z-index: -1;
        }

        .virtual-list {
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
        }
    }
}
</style>
